/*
 * -------------------------------------------------------------------------
 * 设置管理器
 * -------------------------------------------------------------------------
 */

/*app对象实例*/
let app;
const _       = require('lodash');
const fs      = require('fs');
const path    = require('path');
const file    = require('../helper/file/log');
const is      = require('../helper/is');
const logger  = require('../src/logger');
const configs = require('../package.json').configs;

/**
 * 默认配置
 * @type {{bossKey: string, width: number, x: null, y: null, opacity: number, height: number}}
 */
const Default = {
    /*透明度*/
    opacity: 100,
    
    /* exdel 是否开启debug日志，待设置 */
    debug: false,
    
    /*显隐键*/
    bossKey: configs.bossKey.toUpperCase(),
    
    /*是否收起菜单*/
    // menuPackup: false,
    
    /*App窗口设置*/
    width : configs.windowMain.minWidth,
    height: configs.windowMain.minHeight,
    x     : null,
    y     : null
};

/*
 * 初始化
 * @param appInstance
 */
function initialize (appInstance) {
    /*复写app实例*/
    app = appInstance;
}

/**
 * 获取配置
 * @returns {{}|*|{}}
 */
function read () {
    let setting = Default;
    try {
        /*用户设置文件*/
        let settingFile = path.join(app.getPath('appData'), configs.settingDir, 'setting.json');
        
        /*文件存在*/
        if (fs.existsSync(settingFile)) {
            let data = fs.readFileSync(settingFile, 'utf8');
            return _.merge(_.cloneDeep(setting), data ? JSON.parse(data) : {});
        }
        
        /*更新配置*/
        update(setting);
    }
    catch (e) {
        logger.error(e);
    }
    
    return setting;
}

/**
 * 更新配置
 * @param data
 * @returns {{errCode: number, errMsg: string}}
 */
function update (data) {
    try {
        /*修改前配置*/
        let oldSetting = read();
        
        /*配置目录*/
        let settingDir = path.join(app.getPath('appData'), configs.settingDir);
        
        /*尝试创建目录*/
        file.mkdir(settingDir);
        
        /*配置观察者，比对变化项并进行相关处理*/
        const { errCode, errMsg } = watcher(oldSetting, data);
        
        /*合并配置（_.merge()会影响原对象）*/
        let newSetting = _.merge(_.cloneDeep(oldSetting), data);
        
        /*更新文件*/
        (errCode === 0) && fs.writeFileSync(path.join(settingDir, 'setting.json'), JSON.stringify(newSetting, null, 4), 'utf8');
        
        return { errCode, errMsg };
    }
    catch (e) {
        logger.error(e);
        return { errCode: 1, errMsg: '配置更新失败' };
    }
    
    return { errCode: 0, errMsg: '配置更新成功' };
}

/**
 * 配置观察者，比对变化项并进行相关处理
 * @param oldSetting
 * @param updateStting
 * @returns {{errCode: number, errMsg: string}}
 */
function watcher (oldSetting, updateStting) {
    /*尝试更新app透明度*/
    if (!is.undf(updateStting.opacity) && (oldSetting.opacity !== updateStting.opacity)) {
        app.$windowMain.setOpacity(updateStting.opacity / 100);
    }
    
    /*修改显隐键*/
    if (!is.undf(updateStting.bossKey) && (oldSetting.bossKey !== updateStting.bossKey)) {
        /*检测menu中使用的快捷键*/
        let menuMap = app.$Menu.getApplicationMenu().items;
        for (let i = 0; i < menuMap.length; i++) {
            if (menuMap[i].accelerator && menuMap[i].accelerator.toUpperCase() === updateStting.bossKey.toUpperCase()) {
                return { errCode: 1, errMsg: `快捷键 ${updateStting.bossKey.toUpperCase()} 已被占用` };
            }
        }
        
        /*设置快捷键*/
        const shortcutGlobal = require('./shortcut/global');
        if (!shortcutGlobal.update(updateStting.bossKey)) return { errCode: 1, errMsg: '快捷键设置失败' };
    }
    
    return { errCode: 0, errMsg: '配置更新成功' };
}

/**
 * 导出
 * @type {{read: ((function(): ({}|*))|*), update: ((function(*=): {errCode: number, errMsg: string})|*), initialize: initialize}}
 */
module.exports = {
    initialize,
    read,
    update
};
